package com.cctc.rds.raft.core.util;

import sun.misc.Signal;
import sun.misc.SignalHandler;

import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedList;

public class SignalManager {
    private static final Deque<SignalHandler> SIGNAL_HANDLERS = new LinkedList<>();

    static {
        SignalHandler signalHandler = new SignalHandler() {
            @Override
            public void handle(Signal signal) {
                synchronized (SIGNAL_HANDLERS) {
                    if (!SIGNAL_HANDLERS.isEmpty()) {
                        SIGNAL_HANDLERS.parallelStream().forEach(handler -> {
                            System.out.println("触发 INT 信号处理器 -> " + handler.getClass().getName());
                            handler.handle(signal);
                        });
                    }
                }
            }
        };
        Signal.handle(new Signal("INT"), signalHandler);
    }

    public static void addFirst(SignalHandler handler) {
        synchronized (SIGNAL_HANDLERS) {
            SIGNAL_HANDLERS.addFirst(handler);
        }
    }

    public static void addLast(SignalHandler handler) {
        synchronized (SIGNAL_HANDLERS) {
            SIGNAL_HANDLERS.addLast(handler);
        }
    }

    public static void addFirst(Closeable... closeables) {
        synchronized (SIGNAL_HANDLERS) {
            for (Closeable c : closeables) {
                SIGNAL_HANDLERS.addFirst(handler -> {
                    try {
                        c.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                });
            }
        }
    }

    public static void addLast(Closeable... closeables) {
        synchronized (SIGNAL_HANDLERS) {
            for (Closeable c : closeables) {
                SIGNAL_HANDLERS.addLast(handler -> {
                    try {
                        c.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                });
            }
        }
    }


}
